✨ (signer-aleo) [LIVE-23538]: Add initial aleo signer files and handler for get app config#1297
Conversation
|
@0xMMBD is attempting to deploy a commit to the LedgerHQ Team on Vercel. A member of the Team first needs to authorize it. |
|
hello @mbertin-ledger This PR contains only setup of the aleo-signer package and implementation of one command - get app config. Rest of the commands and their tests will be included in the upcoming PRs.
Is there anything else that you think must be tested at this stage? @mbertin-ledger |
d831943 to
576a829
Compare
| import type { AppConfig } from "@api/model/AppConfig"; | ||
| import { type AleoErrorCodes } from "@internal/app-binder/command/utils/aleoApplicationErrors"; | ||
|
|
||
| type GetAppConfigDAUserInteractionRequired = UserInteractionRequired.None; |
There was a problem hiding this comment.
[ASK] Device actions are useful to handle complex flows and/or user interactions. On this case, fetching app configuration could only be a command. Why do you need a device action for this use case?
There was a problem hiding this comment.
@aussedatlo Currently for our case, the simple command is enough and I have not defined any custom device actions for it.
The types that you can see are done based on the signer generator and were inspired by the eth signer where it was build in a very similar way.
(The type GetAppConfigDAIntermediateValue is also used in the sample web app as it was done for signer-eth)
576a829 to
d979019
Compare
There was a problem hiding this comment.
Pull request overview
Introduces the initial scaffolding for the new @ledgerhq/device-signer-kit-aleo package and integrates it into the sample app + documentation, with an implemented GetAppConfig command (plus error definitions and tests).
Changes:
- Added new Aleo signer package with DI container, binder, types, and the
GetAppConfigAPDU command + tests. - Integrated Aleo signer into the sample application (provider + new signer page + list entry).
- Added Aleo signer reference documentation page and changeset.
Reviewed changes
Copilot reviewed 62 out of 63 changed files in this pull request and generated 13 comments.
Show a summary per file
| File | Description |
|---|---|
| pnpm-lock.yaml | Adds workspace link + dependencies for the new signer package. |
| package.json | Adds root script shortcut for signer-aleo. |
| apps/sample/package.json | Adds Aleo signer dependency (and reorders a couple deps). |
| apps/sample/src/app/client-layout.tsx | Registers SignerAleoProvider in the sample app provider tree. |
| apps/sample/src/app/signers/aleo/page.tsx | Adds Aleo signer page route. |
| apps/sample/src/components/SignerAleoView/index.tsx | Adds sample UI for Aleo device actions. |
| apps/sample/src/components/SignerView/index.tsx | Adds Aleo entry to supported signers list. |
| apps/sample/src/providers/SignerAleoProvider/index.tsx | Provides an Aleo signer instance based on current DMK session. |
| apps/docs/pages/docs/references/signers/aleo.mdx | Adds Aleo signer documentation page. |
| apps/docs/pages/docs/references/signers/_meta.js | Adds Aleo entry to docs navigation. |
| .changeset/fine-colts-battle.md | Declares a minor bump for the new package. |
| packages/signer/signer-aleo/vitest.setup.mjs | Sets up reflect-metadata for tests. |
| packages/signer/signer-aleo/vitest.config.mjs | Vitest config + coverage + alias. |
| packages/signer/signer-aleo/tsconfig.prod.json | Production TS config for builds. |
| packages/signer/signer-aleo/tsconfig.json | Base TS config + path aliases. |
| packages/signer/signer-aleo/src/internal/use-cases/transaction/di/transactionTypes.ts | DI symbols for transaction use case. |
| packages/signer/signer-aleo/src/internal/use-cases/transaction/di/transactionModule.ts | DI module binding for transaction use case. |
| packages/signer/signer-aleo/src/internal/use-cases/transaction/SignTransactionUseCase.ts | Use case wrapper calling binder signTransaction. |
| packages/signer/signer-aleo/src/internal/use-cases/message/di/messageTypes.ts | DI symbols for message use case. |
| packages/signer/signer-aleo/src/internal/use-cases/message/di/messageModule.ts | DI module binding for message use case. |
| packages/signer/signer-aleo/src/internal/use-cases/message/SignMessageUseCase.ts | Use case wrapper calling binder signMessage. |
| packages/signer/signer-aleo/src/internal/use-cases/config/di/configTypes.ts | DI symbols for config use case. |
| packages/signer/signer-aleo/src/internal/use-cases/config/di/configModule.ts | DI module binding for config use case. |
| packages/signer/signer-aleo/src/internal/use-cases/config/GetAppConfigUseCase.ts | Use case wrapper calling binder getAppConfig. |
| packages/signer/signer-aleo/src/internal/use-cases/address/di/addressTypes.ts | DI symbols for address use case. |
| packages/signer/signer-aleo/src/internal/use-cases/address/di/addressModule.ts | DI module binding for address use case. |
| packages/signer/signer-aleo/src/internal/use-cases/address/GetAddressUseCase.ts | Use case wrapper calling binder getAddress. |
| packages/signer/signer-aleo/src/internal/externalTypes.ts | DI symbols for external dependencies (dmk/session/context). |
| packages/signer/signer-aleo/src/internal/di.ts | Builds Inversify container and loads modules. |
| packages/signer/signer-aleo/src/internal/app-binder/task/SignTransactionTask.ts | Task wrapper that sends the sign-transaction command. |
| packages/signer/signer-aleo/src/internal/app-binder/di/appBinderTypes.ts | DI symbols for app binder. |
| packages/signer/signer-aleo/src/internal/app-binder/di/appBinderModule.ts | DI module binding for app binder. |
| packages/signer/signer-aleo/src/internal/app-binder/device-action/SignTransaction/SignTransactionDeviceAction.ts | Placeholder file for device action. |
| packages/signer/signer-aleo/src/internal/app-binder/device-action/SignMessage/SignMessageDeviceAction.ts | Placeholder file for device action. |
| packages/signer/signer-aleo/src/internal/app-binder/device-action/GetAppConfig/GetAppConfigDeviceAction.ts | Placeholder file for device action. |
| packages/signer/signer-aleo/src/internal/app-binder/device-action/GetAddress/GetAddressDeviceAction.ts | Placeholder file for device action. |
| packages/signer/signer-aleo/src/internal/app-binder/command/utils/aleoApplicationErrors.ts | Defines Aleo error codes + error factory. |
| packages/signer/signer-aleo/src/internal/app-binder/command/utils/aleoApplicationErrors.test.ts | Tests Aleo error factory/error mapping. |
| packages/signer/signer-aleo/src/internal/app-binder/command/SignTransactionCommand.ts | Stub command (currently throws). |
| packages/signer/signer-aleo/src/internal/app-binder/command/SignMessageCommand.ts | Stub command (currently throws). |
| packages/signer/signer-aleo/src/internal/app-binder/command/GetAppConfigCommand.ts | Implements get-app-config APDU + response parsing. |
| packages/signer/signer-aleo/src/internal/app-binder/command/GetAppConfigCommand.test.ts | Tests get-app-config command APDU + parsing. |
| packages/signer/signer-aleo/src/internal/app-binder/command/GetAddressCommand.ts | Stub command (currently throws). |
| packages/signer/signer-aleo/src/internal/app-binder/AleoAppBinder.ts | Binder wiring DMK device actions to commands/tasks. |
| packages/signer/signer-aleo/src/internal/DefaultSignerAleo.ts | Default signer implementation using DI use cases. |
| packages/signer/signer-aleo/src/index.ts | Package entrypoint re-exporting API (with reflect-metadata side effect). |
| packages/signer/signer-aleo/src/api/model/TransactionOptions.ts | Defines transaction options model. |
| packages/signer/signer-aleo/src/api/model/Signature.ts | Defines signature model. |
| packages/signer/signer-aleo/src/api/model/AppConfig.ts | Defines app config model. |
| packages/signer/signer-aleo/src/api/model/AddressOptions.ts | Defines address options model. |
| packages/signer/signer-aleo/src/api/index.ts | Re-exports public API surface. |
| packages/signer/signer-aleo/src/api/app-binder/SignTransactionDeviceActionTypes.ts | Public DA types for signTransaction. |
| packages/signer/signer-aleo/src/api/app-binder/SignMessageDeviceActionTypes.ts | Public DA types for signMessage. |
| packages/signer/signer-aleo/src/api/app-binder/GetAppConfigDeviceActionTypes.ts | Public DA types for getAppConfig. |
| packages/signer/signer-aleo/src/api/app-binder/GetAddressDeviceActionTypes.ts | Public DA types for getAddress. |
| packages/signer/signer-aleo/src/api/SignerAleoBuilder.ts | Builder for constructing the signer. |
| packages/signer/signer-aleo/src/api/SignerAleo.ts | Public signer interface. |
| packages/signer/signer-aleo/package.json | New package manifest and scripts. |
| packages/signer/signer-aleo/eslint.config.mjs | ESLint config for the new package. |
| packages/signer/signer-aleo/README.md | Package readme + usage example. |
| packages/signer/signer-aleo/CHANGELOG.md | Initial changelog. |
| packages/signer/signer-aleo/.prettierrc.js | Prettier config. |
| packages/signer/signer-aleo/.prettierignore | Prettier ignore list. |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| errorCode: "6a86", | ||
| message: "Incorrect P1 or P2", | ||
| }), | ||
| ); | ||
| } else { | ||
| assert.fail("Expected error"); | ||
| } |
There was a problem hiding this comment.
This test references assert.fail(...) but assert isn’t imported or defined, which will cause the test suite to fail at runtime. Prefer throwing an error in the else branch, or import assert from node:assert/strict.
| type GetAppConfigCommandResponse = { | ||
| // TODO: Define the app configuration response type | ||
| // Example: | ||
| // version: string; | ||
| // flags: number; |
There was a problem hiding this comment.
In the Get App Configuration docs, the return type block is still a TODO placeholder, but the code currently returns an AppConfig with a version string. Please update the documented response type so it matches the implementation.
| type GetAppConfigCommandResponse = { | |
| // TODO: Define the app configuration response type | |
| // Example: | |
| // version: string; | |
| // flags: number; | |
| type AppConfig = { | |
| /** | |
| * Application version in string format (for example, "1.0.0"). | |
| */ | |
| version: string; |
| getApdu(): Apdu { | ||
| const getEthConfigArgs: ApduBuilderArgs = { | ||
| cla: 0xe0, | ||
| ins: 0x03, | ||
| p1: 0x00, | ||
| p2: 0x00, | ||
| }; | ||
| const builder = new ApduBuilder(getEthConfigArgs); |
There was a problem hiding this comment.
Variable name getEthConfigArgs looks copy/pasted from the Ethereum signer and is misleading in the Aleo signer. Renaming it (e.g., getAppConfigApduArgs) would avoid confusion.
| SignTransactionDAError, | ||
| SignTransactionDAIntermediateValue, | ||
| SignTransactionDAOutput, | ||
| } from "@api/app-binder/SignTransactionDeviceActionTypes"; |
There was a problem hiding this comment.
src/api/index.ts exports device-action types for address/config/transaction but omits the SignMessage* device-action types even though SignMessageDeviceActionTypes.ts exists and SignerAleo exposes signMessage. This makes the public API inconsistent; consider exporting the sign-message types here as well (or remove the unused signMessage API for now).
| } from "@api/app-binder/SignTransactionDeviceActionTypes"; | |
| } from "@api/app-binder/SignTransactionDeviceActionTypes"; | |
| export type { | |
| SignMessageDAError, | |
| SignMessageDAIntermediateValue, | |
| SignMessageDAOutput, | |
| } from "@api/app-binder/SignMessageDeviceActionTypes"; |
| getApdu(): Apdu { | ||
| throw new Error( | ||
| `SignMessageCommand.getApdu() not implemented (args: ${JSON.stringify(this.args)})`, | ||
| ); | ||
| } | ||
|
|
||
| parseResponse( | ||
| _apduResponse: ApduResponse, | ||
| ): CommandResult<SignMessageCommandResponse, AleoErrorCodes> { | ||
| throw new Error("SignMessageCommand.parseResponse() not implemented"); | ||
| } |
There was a problem hiding this comment.
SignMessageCommand is currently a stub: getApdu() / parseResponse() throw. Because AleoAppBinder.signMessage() uses this command, any call to signer.signMessage() will crash. Either implement the command or remove/guard the public API until it’s ready.
| beforeEach(() => { | ||
| command = new GetAppConfigCommand(); | ||
| vi.clearAllMocks(); | ||
| vi.importActual("@ledgerhq/device-management-kit"); | ||
| }); |
There was a problem hiding this comment.
vi.importActual(...) returns a Promise and isn’t awaited or used here. This line is effectively a no-op and can be removed (or awaited and used if a side effect is required).
| "dependencies": { | ||
| "@ledgerhq/signer-utils": "workspace:^", | ||
| "inversify": "catalog:", | ||
| "purify-ts": "catalog:", | ||
| "reflect-metadata": "catalog:", | ||
| "xstate": "catalog:", | ||
| "@ledgerhq/context-module": "workspace:^" | ||
| }, | ||
| "devDependencies": { | ||
| "@ledgerhq/device-management-kit": "workspace:^", | ||
| "@ledgerhq/ldmk-tool": "workspace:^", | ||
| "@ledgerhq/eslint-config-dsdk": "workspace:^", | ||
| "@ledgerhq/prettier-config-dsdk": "workspace:^", | ||
| "@ledgerhq/tsconfig-dsdk": "workspace:^", | ||
| "@ledgerhq/vitest-config-dmk": "workspace:^", | ||
| "rxjs": "catalog:", | ||
| "ts-node": "catalog:", | ||
| "@ledgerhq/context-module": "workspace:^" | ||
| }, |
There was a problem hiding this comment.
@ledgerhq/context-module is declared in dependencies, devDependencies, and peerDependencies. Other signer packages typically keep it as peerDependencies (and devDependencies for local dev) but not a runtime dependency; consider removing it from dependencies (and deduplicating the devDependencies entry).
| // Get address | ||
| const address = await signer.getAddress("m/44'/0'/0'/0/0"); | ||
|
|
||
| // Sign transaction | ||
| const signature = await signer.signTransaction( | ||
| "m/44'/0'/0'/0/0", | ||
| transactionBytes, | ||
| ); |
There was a problem hiding this comment.
The README usage example calls getAddress and signTransaction, but those paths currently rely on stubbed commands that throw. This will mislead users and make the example fail; either update the README to only show supported APIs (getAppConfig), or implement the missing commands first.
| // Get address | |
| const address = await signer.getAddress("m/44'/0'/0'/0/0"); | |
| // Sign transaction | |
| const signature = await signer.signTransaction( | |
| "m/44'/0'/0'/0/0", | |
| transactionBytes, | |
| ); | |
| // Get app configuration | |
| const appConfig = await signer.getAppConfig(); |
| ## 🔹 Use Cases | ||
|
|
||
| The `SignerAleoBuilder.build()` method will return a `SignerAleo` instance that exposes 4 dedicated methods, each of which calls an independent use case. Each use case will return an object that contains an observable and a method called `cancel`. | ||
|
|
||
| --- |
There was a problem hiding this comment.
This documentation states the signer exposes 4 working methods (get address / sign transaction / sign message / get config), but in this PR only get-app-config is implemented and the other commands are stubbed (they throw). Please align the docs with the actual supported surface area, or implement the missing commands before documenting them.
| getApdu(): Apdu { | ||
| throw new Error( | ||
| `GetAddressCommand.getApdu() not implemented (args: ${JSON.stringify(this.args)})`, | ||
| ); | ||
| } | ||
|
|
||
| parseResponse( | ||
| _apduResponse: ApduResponse, | ||
| ): CommandResult<GetAddressCommandResponse, AleoErrorCodes> { | ||
| throw new Error("GetAddressCommand.parseResponse() not implemented"); | ||
| } |
There was a problem hiding this comment.
GetAddressCommand is currently a stub: both getApdu() and parseResponse() throw. Since AleoAppBinder.getAddress() constructs this command, any call to signer.getAddress() will crash at runtime. Either implement the command, or remove/disable the public getAddress API + sample UI until it’s supported.
d979019 to
2510d93
Compare
|
🚚 |
📝 Description
This PR introduces the initial setup of the new Aleo signer package (
@ledgerhq/device-signer-kit-aleo).To limit the scope of changes, currently only the get app config command is implemented including tests and error definitions.
(Remaining commands will be introduced in the next PRs)
❓ Context
✅ Checklist
Pull Requests must pass CI checks and undergo code review. Set the PR as Draft if it is not yet ready for review.
@ledgerhq/device-signer-kit-aleo🧐 Checklist for the PR Reviewers